package com.hz.ftl.util;

import com.hz.ftl.bean.ImageInfo;
import freemarker.template.Configuration;
import freemarker.template.Version;
import org.springframework.util.Base64Utils;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Created by kevin on 2022/5/19 10:57
 */
public class WordUtil {

    private static Configuration configuration;

    static {
        // 创建实例
        configuration = new Configuration(new Version("2.3.30"));
        // 设置编码
        configuration.setDefaultEncoding(StandardCharsets.UTF_8.name());
        // 获取模板路径
        configuration.setClassLoaderForTemplateLoading(WordUtil.class.getClassLoader(), "/templates");
    }

    private WordUtil() {
    }

    public static WordUtil getInstance() {
        return WordUtilHolder.instance;
    }

    static class WordUtilHolder {
        private static final WordUtil instance = new WordUtil();
    }


    /**
     * 写word文件到某个位置
     *
     * @param map      模版数据
     * @param path     导出的路径
     * @param ftlFile  工程ftl文件名
     * @param fileName 保存的word文件名
     */
    public void exportWordByFile(Map map, String path, String ftlFile, String fileName) {
        Writer writer = null;
        try {
            // 导出的文件地址
            File exportDirs = new File(path);
            //目录不存在，则创建
            if (!exportDirs.exists()) {
                exportDirs.mkdirs();
            }
            // 输出流
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path + fileName), StandardCharsets.UTF_8.name()));
            // 生成word文件
            configuration.getTemplate(ftlFile).process(map, writer);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(writer);
        }
    }

    /**
     * 通过浏览器下载word文件
     *
     * @param map      模版数据
     * @param ftlFile  ftl文件名
     * @param response 请求响应
     */
    public void exportWordByBrowser(HttpServletResponse response, Map map, String ftlFile, String fileName) {
        PrintWriter writer = null;
        try {
            // 设置响应头
            response.setContentType("application/msword");
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
            // 输出流
            writer = response.getWriter();
            // 生成word文件
            configuration.getTemplate(ftlFile).process(map, writer);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(writer);
        }
    }


    /**
     * 假设的资源图片
     *
     * @return base64后的图片集合
     */
    public List<ImageInfo> getFakeImages() {
        List<ImageInfo> lists = new ArrayList<>();
        try {
            for (int i = 0; i < 3; i++) {
                String path = Objects.requireNonNull(WordUtil.class.getClassLoader().getResource("static/images/icon" + i + ".png")).getPath();
                // 获取图片宽高
                BufferedImage image = ImageIO.read(new FileInputStream(path));
                // 图片的原始宽高
                int width = image.getWidth() / 2;
                int height = image.getHeight() / 2;
                lists.add(new ImageInfo(String.valueOf(i), getImgBase64Str(new FileInputStream(path)), width, height));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return lists;
    }

    /**
     * 图片流转base64
     *
     * @param input 图片流转
     * @return base64后的图片
     */
    private String getImgBase64Str(InputStream input) {
        ByteArrayOutputStream output = null;
        try {
            output = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int numBytesRead;
            while ((numBytesRead = input.read(buf)) != -1) {
                output.write(buf, 0, numBytesRead);
            }
            byte[] data = output.toByteArray();
            return Base64Utils.encodeToString(data);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(output, input);
        }
        return "";
    }

    /**
     * 关流
     *
     * @param writer 输出流
     */
    private void close(Writer writer) {
        try {
            if (writer != null) {
                writer.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void close(ByteArrayOutputStream output, InputStream input) {
        try {
            if (output != null) {
                output.close();
            }
            if (input != null) {
                input.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
